package com.nd.rj.common.register;

import java.util.UUID;

import org.apache.http.HttpStatus;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnKeyListener;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;

import com.common.StarAppConfig;
import com.common.StarAppConst;
import com.common.android.utils.task.progressTask.ProgressTask;
import com.common.android.utils.task.progressTask.ProgressTask.IProgressDialogIteration;
import com.common.utils.EncryptTool;
import com.nd.rj.common.R;
import com.nd.rj.common.login.NdLoginComFun;
import com.nd.rj.common.login.DataDef.NdLoginConst;
import com.nd.rj.common.login.atomoperation.OperUserInfo;
import com.nd.rj.common.login.communication.uapCom;
import com.product.android.business.ApplicationVariable;
import com.product.android.business.bean.UserInfo;

/**
 * 注册接口实现类
 * 
 * <br>Created 2014-10-22 上午11:16:21
 * @version  V1.7
 * @author   linsj		
 *
 * @see 	 
 * 
 * Copyright(c) 2009-2014, TQ Digital Entertainment, All Rights Reserved
 *
 */
public class NdRegistManagerImpl implements INdRegistManagerOperate{
    /** TAG */
    private static final String TAG = NdRegistManagerImpl.class.getSimpleName();
    
    /**注册结果监听接口*/
	private IRegisterationListener mIRegistListener;
	
	/**是否需要在注册处理时，显示等待对话框*/
	private boolean mbNeedWaitDlg;
	
	/**处理时的等待对话框*/
	private Dialog mWaitDlg;
    /** 用户是否点击取消 */
    private boolean mbCanceled = false;
	/**
     * 构造方法
     * Creates a new instance of NdRegistManagerImpl.
     * <br>Created 2014-10-22 上午11:16:54
     */
    public NdRegistManagerImpl(){
    }

    @Override
    public void setIsNeedWaitDlg(boolean bNeed) {
        mbNeedWaitDlg = bNeed;
    }

    @Override
    public void setRegisterWaitDlg(Dialog waitDlg) {
        mWaitDlg = waitDlg;
    }

	@Override
	public void setRegisterListener(IRegisterationListener listener){
	    mIRegistListener = listener;
	}
	
    @Override
    public void doSendCheckCode(Context context, String strPhoneNumber) {
        new ProgressSendCode(context, strPhoneNumber).execute();
    }

    @Override
    public void doRegisterMobile(Context context, UserInfo info, String strCheckCode) {
        new ProgressRegist(context, strCheckCode, info).execute();
    }
	/**
	 * 处理注册
	 * 
	 * <br>Created 2014-10-22 上午11:21:44
	 * @version  NdRegistManagerImpl
	 * @author   linsj		
	 *
	 * @see 	 
	 * 
	 * Copyright(c) 2009-2014, TQ Digital Entertainment, All Rights Reserved
	 *
	 */
	private class ProgressRegist extends ProgressTask {
	    /**短信验证码*/
	    private String mstrCheckCode;
	    
	    /**用户信息*/
	    private UserInfo mUserInfo;
	    
	    /**
	     * 构造方法
	     * Creates a new instance of ProgressRegist.
	     * <br>Created 2014-10-22 上午11:18:06
	     * @param context      上下文
	     * @param strCheckCode 短信验证码
	     * @param info         用户信息
	     * @param resId        用户于显示等待信息的字符串资源ID
	     */
        public ProgressRegist(Context context, String strCheckCode, UserInfo info) {
            super(context, R.string.nd_regist_registing);
            mstrCheckCode = strCheckCode;
            mUserInfo = info;
            progressDialogIteration = getProgressDlgIteration();
        }

        @Override
        protected void doSuccess() {
        	mIRegistListener.onRegisterSuccess(mUserInfo);
        }

        @Override
        protected Integer doInBackground(Void... params) {
        	//生成一个blowfish，用于票据登录
            mbCanceled = false;
            String blowfish=UUID.randomUUID().toString();
			mUserInfo.setBlowfish(blowfish);
            return regPhoneFrom99(mUserInfo, mstrCheckCode, mErrorMsg);       
        }

        @Override
        protected void doFail(int result) {
            if (mbCanceled) {
                return;
            }
            mIRegistListener.onRegisterFail(result,mErrorMsg);
        }
        
        /**
         * 手机注册 <br>
         * Created 2014-9-9 下午3:52:04
         * 
         * @param userInfo 用户信息
         * @param verifycode
         *            手机短信验证码，必须
         *@param errorMessage
         *            返回的消息
         * @return 201 注册成功 204 手机号码为空/昵称为空/密码为空/短信验证码为空/短信验证码不正确 206 手机已绑定，或者手机号码已经被注册为91通行证，
         *         同时会返回uid与username 404 应用ID为空/应用ID不存在 406 已经绑定别名，无法注册/当前帐号已绑定且达到绑定个数，无法注册/帐号已存在，无法注册
         *         412 注册失败 409 注册失败，其他原因
         * @author gpy
         */
        private int regPhoneFrom99(UserInfo userInfo, String verifycode,StringBuilder errorMessage) {
            if (null == userInfo || TextUtils.isEmpty(userInfo.getUserName())
                    || TextUtils.isEmpty(userInfo.getUserPass()) || TextUtils.isEmpty(verifycode)) {
                return HttpStatus.SC_CONFLICT;
            }
            errorMessage.delete(0, errorMessage.length());
            StringBuilder receive = new StringBuilder();
            
            int ireturn =  uapCom.getInstance(mContext).regPhoneFrom99(userInfo, verifycode, receive);
            if (ireturn == 0) {
                // 成功就直接登陆
                // 记录用户信息
                try {
                    JSONObject json = new JSONObject(receive.toString());
                    userInfo.setSessionId(json.getString("sid"));
                    // 为了避免改动到allcommon，这边把所有的UAP登录的时候的OAPUID也设置成UID
                    userInfo.setUapUid(json.getLong("uid"));
                    userInfo.setOapUid(json.getLong("uid"));
                    userInfo.setTicket(json.getString("ticket"));
                    // 密码加密
                    userInfo.setUserPass(NdLoginComFun.RSAEncrypt(userInfo.getUserPass(), NdLoginConst.MODULUS,
                            NdLoginConst.PUBEXP));
                    userInfo.setUserPassMixedMd5(EncryptTool.getMD5str(userInfo.getUserPass(),
                            EncryptTool.TYPE_PSW).toLowerCase());
                    ireturn = OperUserInfo.getInstance().SetUserInfo(userInfo);

                    String token = json.getString("token");
                    if(! TextUtils.isEmpty(token)) {
                        StarAppConfig.setConfig(StarAppConfig.CONFIG_PAY_TOKEN, token);

                        SharedPreferences sp = ApplicationVariable.INSTANCE.applicationContext
                                .getSharedPreferences(StarAppConst.PAY.PAY_SHAREDPREFERENCES,
                                        Activity.MODE_PRIVATE);
                        SharedPreferences.Editor editor = sp.edit();

                        try {
                            token = EncryptTool.byte2Hex(EncryptTool.desEncrypt(token, StarAppConst.PAY.PAY_ENCRYPT_KEY));
                        } catch (Exception e) {
                            Log.e("NdRegistManagerImpl", e.getMessage());
                            token = "";
                        }

                        editor.putString(userInfo.getUapUid()+"", token);
                        editor.commit();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    errorMessage.append(mContext.getString(R.string.nd_json_error));
                }
            } else {
                if (0 == receive.length()) {
                    getErrMsgIfNoReceive(mContext, errorMessage, ireturn);
                } else {
                    errorMessage.append(receive);
                }
            }
            return ireturn;
            
        }
    }
	
	/**
     * 出错时，接口可能没有返回错误信息，这里根据返回码（资源值）去取，取不到就提示未知错误 <br>
     * Created 2014-5-22 下午9:37:47
     * 
     * @param context    上下文
     * @param sbErrMsg   用于返回错误信息给调用者
     * @param iReturn   接口返回码
     * @author : linsj
     */
    private void getErrMsgIfNoReceive(Context context, StringBuilder sbErrMsg, int iReturn) {
        try {
            sbErrMsg.append(context.getString(iReturn));
        } catch (Exception e) {
            sbErrMsg.append(context.getString(R.string.nd_unknow_error)).append(iReturn);
        }
    }
    
	/**
	 * ClassName:ProgressSendCode
	 * Function: 同步获取验证码
	 * Reason:	 
	 * @author   cb		
	 * @version  Ver 1.0.0
	 * @Date	 2014	2014-4-3		下午4:24:16
	 *
	 * @see 	 
	 */
	private class ProgressSendCode extends ProgressTask {		
		private final int DUPLICATE_MOBILE_AS_ACCOUNT = 20250;
		
		private final int ALREADY_EXIST_MOBLIE = 20090;
		
		/**待注册手机号码*/
		private String mstrPhoneNumber;

		/**
         * 构造方法
         * Creates a new instance of ProgressSendCode.
         * <br>Created 2014-10-22 上午11:18:06
         * @param context           上下文
         * @param strPhoneNumber    待注册手机号码
         * @param resId             用户于显示等待信息的字符串资源ID
         */
        public ProgressSendCode(Context context, String strPhoneNumber) {
            super(context, R.string.nd_send_code_registing);  
            mstrPhoneNumber = strPhoneNumber; 
            progressDialogIteration = getProgressDlgIteration();
        }

        @Override
        protected void doSuccess() {
        	mIRegistListener.onSendCheckCodeSuccess();
        }

        @Override
        protected Integer doInBackground(Void... params) {
            return regSendCode(mstrPhoneNumber, NdLoginConst.REGISTER_CODE_TYPE,
                    NdLoginConst.REGISTER_TYPE_MOBILE, mErrorMsg);
        }

        @Override
        protected void doFail(int result) {
            if (ALREADY_EXIST_MOBLIE == result || DUPLICATE_MOBILE_AS_ACCOUNT == result) {
                // 已注册
                mIRegistListener.onGetCheckRepeat();
            } else {
                if(0 != mErrorMsg.length()){
                    mIRegistListener.onGetCheckCodeFail(result,mErrorMsg);
                }else{
                    mErrorMsg.append(mContext.getString(R.string.regist_send_code_other_err));
                    mIRegistListener.onGetCheckCodeFail(result,mErrorMsg);
                }
            }
        }
        
        /**
         * 注册发送手机短信验证码 <br>
         * Created 2014-9-9 下午3:30:57
         * 
         * @param phone
         *            手机号码，必须，11位整型
         * @param type
         *            验证码类型，=4 发送手机注册验证码，必须
         * @param btype
         *            注册类型，=1 通用手机注册
         *@param errorMessage
         *            返回的消息
         * @return 200 发送成功 204 短信验证码类型为空或不合法/手机号码为空/手机号码不合法 206 手机已被绑定 406 发送短信验证码失败（别名手机已存在无法注册） 409
         *         其他原因导致失败
         * @author gpy
         */
        public int regSendCode(String phone, int type, int btype,StringBuilder errorMessage) {
            errorMessage.delete(0, errorMessage.length());
            StringBuilder receive = new StringBuilder();
            int ireturn = uapCom.getInstance(mContext).regSendCode(phone, type, btype, receive);

            // 得到错误信息
            if (0 != ireturn) {
                if (0 == receive.length()) {
                    getErrMsgIfNoReceive(mContext, errorMessage, ireturn);
                } else {
                    errorMessage.append(receive);
                }
            }

            return ireturn;
        }
    }
	
	/**
     * 获得等待框
     * 三种情况：不需要显示等待框；需要显示指定的等待框；需要显示默认的等待框
     * 
     * <br>Created 2014-10-22 下午1:05:29
     * @return
     * @author       linsj
     */
    private IProgressDialogIteration getProgressDlgIteration(){
        IProgressDialogIteration iter = null;
        if(!mbNeedWaitDlg){
            //不需要显示等待框，就制造一个默认的IProgressDialogIteration，啥事情都不干
            iter = new IProgressDialogIteration() {              
                @Override
                public void onShow() {
                }
                
                @Override
                public void onDismiss() {
                }
            }; 
        }else if(null != mWaitDlg){
            iter = new IProgressDialogIteration() {              
                @Override
                public void onShow() {
                    mWaitDlg.setCanceledOnTouchOutside(false);
                    mWaitDlg.setOnKeyListener(new OnKeyListener() {
                        @Override
                        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                            // 屏蔽Search键(因为按搜索按键会被关闭)
                            switch (event.getKeyCode()) {
                            case KeyEvent.KEYCODE_SEARCH:
                                return true;
                            case KeyEvent.KEYCODE_BACK:
                                mbCanceled = true;
                                mWaitDlg.dismiss();
                                return true;
                            default:
                                return false;
                            }
                        }
                    });
                    mWaitDlg.show();
                }
                
                @Override
                public void onDismiss() {
                    mWaitDlg.dismiss();
                }
            };
        }
        
        return iter;
    }
}
